python文件操作

文件是数据的抽象和集合

文件处理的步骤:打开-操作-关闭

文件操作的全过程:python解释器–>system api–>system call–>虚拟文件系统–>设备驱动–>硬件设备

打开文件

open(file, mode=’r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

1
2
3
f = open(filename, mode, encoding) # open()函数打开文件,文件处于占用状态,变量f是文件句柄
# 读写操作
f.close() # 关闭文件
1
2
3
# 推荐使用这种方法
with open(file, mode) as f:
f.read()
  • file:文件路径和名称,源文件同目录可省路径

  • mode:文本 or 二进制,读 or 写 or 追加 or 组合

    文本方式和二进制方式是文件的两种不同展示方式

    文本方式采用统一的编码解释文件

    二进制方式采用字节解释文件

    | mode | 含义 |
    | —- | ——————————————————- |
    | ‘r’ | 只读模式,默认值,如果文件不存在,返回FileNotFoundError |
    | ‘w’ | 覆盖写模式,文件不存在则创建,存在则完全覆盖 |
    | ‘x’ | 创建写模式,文件不存在则创建,存在则返回FileExistsError |
    | ‘a’ | 追加写模式,文件不存在则创建,存在则在文件最后追加内容 |
    | ‘b’ | 二进制文件模式 |
    | ‘t’ | 文本文件模式,默认值 |
    | ‘+’ | 与r/w/x/a一同使用,在原功能基础上增加同时读写功能 |

  • encoding:指定打开文件时采用的编码方式

读取文件

方法 描述
f.read(size=-1) 读入全部内容,如果给出参数,读入前size长度
f.readline(size=-1) 读入一行内容,如果给出参数,读入该行前size长度
f.readlines(hint=-1) 读入文件所有行,以每行为元素形成列表。如果给出参数,读入前hint个字符所在行的所有字符,然后把这些字符按行拆分成列表。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 搞不清楚file.readlines(hint)的参数hint啥意思,写个脚本测试下。
f = open('tt.txt', 'r')
print('---这里是文档原文---')
print(f.read())
print('---文档原文结束了---')

s = set() # 能够都到的行数
for i in range(1,999):
#文件指针设定到开头
f.seek(0)

a = f.readlines(i)
if not len(a) in s:
# 读到了新行
print('使用参数%d读到了%d行,这一行有%d个字符'%(i,len(a),len(a[-1])))
s.add(len(a))

f.close()


'''输出结果
---这里是文档原文---
SQLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以集成。

Python就内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。

在使用SQLite前,我们先要搞清楚几个概念:

表是数据库中存放关系数据的集合,一个数据库里面通常都包含多个表,比如学生的表,班级的表,学校的表,等等。表和表之间通过外键关联。

要操作关系数据库,首先需要连接到数据库,一个数据库连接称为Connection;

连接到数据库后,需要打开游标,称之为Cursor,通过Cursor执行SQL语句,然后,获得执行结果。

Python定义了一套操作数据库的API接口,任何数据库要连接到Python,只需要提供符合Python标准的数据库驱动即可。

由于SQLite的驱动内置在Python标准库中,所以我们可以直接来操作SQLite数据库。

我们在Python交互式命令行实践一下:
---文档原文结束了---
使用参数1读到了1行,这一行有93个字符
使用参数93读到了2行,这一行有1个字符
使用参数94读到了3行,这一行有54个字符
使用参数148读到了4行,这一行有1个字符
使用参数149读到了5行,这一行有24个字符
使用参数173读到了6行,这一行有1个字符
使用参数174读到了7行,这一行有65个字符
使用参数239读到了8行,这一行有1个字符
使用参数240读到了9行,这一行有41个字符
使用参数281读到了10行,这一行有1个字符
使用参数282读到了11行,这一行有52个字符
使用参数334读到了12行,这一行有1个字符
使用参数335读到了13行,这一行有64个字符
使用参数399读到了14行,这一行有1个字符
使用参数400读到了15行,这一行有47个字符
使用参数447读到了16行,这一行有1个字符
使用参数448读到了17行,这一行有20个字符
'''

'''
结论:参数hint的含义是,读入前hint个字符所在行的所有字符,然后把这些字符按行拆分成列表。
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#------小文件处理-------------
f = open(file, 'r')
txt = f.read()
#对全文txt进行处理
f.close()
#---------------------------

#----结构化、大文件处理--------
fi = open( fname, "r")
txt = fi.read (20)
while txt != "":
# 对 txt 进行处理
txt = fi.read (20)
fi.close()
#---------------------------

#----一次读入,分行处理--------
fi = open( fname, "r")
for line in fi.readlines ():
# 对 line 进行处理
fi.close ()
#---------------------------

#----分行读入,逐行处理--------
fi = open( fname, "r")
for line in fi:
# 对 line 进行 处理
fi.close ()

写入文件

方法 描述
f.write(s) 向文件写入一个字符串或字节流
f.writelines(lines) 将一个元素全为字符串的可迭代对象写入文件

写缓存机制:不调用close()、flush()或者缓冲区未满,不会将缓冲区数据写入磁盘

文件指针

直接读写的痛点

  • 写入文件后,必须打开才能读取写入的内容
  • 读取文件后,无法重新再次读取读过的内容

查看当前文件指针的位置

  • f.tell()

    返回一个整数

改变指针位置

  • f.seek(offset, whence=0)

    offset是相对whence的偏移量,可正可负可0

whence 含义
0 文件开头
1 当前位置
2 文件结尾
1
2
3
4
5
6
7
fo = open("output.txt","w+")
ls = ["中国", "法国", "美国"]
fo.writelines(ls)
fo.seek(0) # 回到文件开头
for line in fo:
print(line)
fo.close()

关闭文件

f.close()

为什么要关闭文件?

  • 将写缓存同步到磁盘

  • Linux每个进程打开的文件个数是有限的

文件对象的属性和方法

| buffer
|
| closed
|
| encoding
| Encoding of the text stream.
|
| Subclasses should override.
|
| errors
| The error setting of the decoder or encoder.
|
| Subclasses should override.
|
| line_buffering
|
| name
|
| newlines
| Line endings translated so far.
|
| Only line endings translated during reading are considered.
|
| Subclasses should override.
|
| write_through

fileno(self, /)
| Returns underlying file descriptor if one exists.
|
| OSError is raised if the IO object does not use a file descriptor.

标准文件

  • 标准输入:sys.stdin
  • 标准输出:sys.stdout
  • 标准错误:sys.stderr
  • 命令行参数:sys.argv